/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { assert, beforeAll, describe, test } from 'vitest';
import { CHECK_MODE, testCaseCheck } from '../common/testCommon';
import ConsoleWithinHighFrequencyFunc from "../../../../src/checker/dsl/ConsoleWithinHighFrequencyFunc";
import path from 'path';
import { CheckEntry, Rule } from '../../../../src/Index';

let realPath: string = '';
let checkEntry: CheckEntry;

beforeAll(async () => {
    const rule: Rule = new Rule('');
    checkEntry = await testCaseCheck('./test/unittest/sample/ConsoleWithinHighFrequencyFunc', rule, CHECK_MODE.FILE2CHECK, ConsoleWithinHighFrequencyFunc, false, true);
    realPath = checkEntry.scene.getRealProjectDir()
})

describe('ConsoleWithinHighFrequencyFunc Flaw Cases', () => {
    test('ConsoleWithinHighFrequencyFuncReport1 should be detected', () => {
        const detectFile: string = path.join(realPath, 'Report/ConsoleWithinHighFrequencyFuncReport1.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.isAbove(detectFileReport?.issues.length, 0, 'Should detect console.log in onMouse callback');
    });

    test('ConsoleWithinHighFrequencyFuncReport2 should be detected', () => {
        const detectFile: string = path.join(realPath, 'Report/ConsoleWithinHighFrequencyFuncReport2.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.isAbove(detectFileReport?.issues.length, 0, 'Should detect console.log in onTouch callback');
    });

    test('ConsoleWithinHighFrequencyFuncReport3 should be detected', () => {
        const detectFile: string = path.join(realPath, 'Report/ConsoleWithinHighFrequencyFuncReport3.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.isAbove(detectFileReport?.issues.length, 0, 'Should detect console.error in onScroll callback');
    });

    test('ConsoleWithinHighFrequencyFuncReport4 should be detected', () => {
        const detectFile: string = path.join(realPath, 'Report/ConsoleWithinHighFrequencyFuncReport4.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.isAbove(detectFileReport?.issues.length, 0, 'Should detect console.warn in onDragMove callback');
    });
})

describe('ConsoleWithinHighFrequencyFunc Good Cases', () => {
    test('ConsoleWithinHighFrequencyFuncNoReport1 should not be detected', () => {
        const detectFile: string = path.join(realPath, 'NoReport/ConsoleWithinHighFrequencyFuncNoReport1.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.equal(detectFileReport?.issues.length, 0, 'Should not detect issues in empty onMouse callback');
    });

    test('ConsoleWithinHighFrequencyFuncNoReport2 should not be detected', () => {
        const detectFile: string = path.join(realPath, 'NoReport/ConsoleWithinHighFrequencyFuncNoReport2.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.equal(detectFileReport?.issues.length, 0, 'Should not detect issues when console.log is outside callback');
    });

    test('ConsoleWithinHighFrequencyFuncNoReport3 should not be detected', () => {
        const detectFile: string = path.join(realPath, 'NoReport/ConsoleWithinHighFrequencyFuncNoReport3.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.equal(detectFileReport?.issues.length, 0, 'Should not detect issues in callback without console methods');
    });

    test('ConsoleWithinHighFrequencyFuncNoReport4 should not be detected', () => {
        const detectFile: string = path.join(realPath, 'NoReport/ConsoleWithinHighFrequencyFuncNoReport4.ets');
        const detectFileReport = checkEntry.fileChecks.find((fileCheck) => fileCheck.arkFile.getFilePath() === detectFile);
        assert.isDefined(detectFileReport, 'The file path is error.');
        assert.equal(detectFileReport?.issues.length, 0, 'Should not detect issues in valid callback implementation');
    });
})
